<template>
  <ion-page>
    <ion-header>
      <ion-toolbar>
        <ion-searchbar v-model="searchQuery" :debounce="500" @ionInput="handleInput($event)"></ion-searchbar>
        <div class="filter-buttons">
          <div class="checkbox-container">
            <ion-checkbox 
              v-model="showGRB" 
              label-placement="end" 
              class="small-checkbox"
              @ionChange="handleCheckboxChange"
            >GRB GRM</ion-checkbox>
            <ion-checkbox 
              v-model="showGW" 
              label-placement="end" 
              class="small-checkbox gw-checkbox"
              @ionChange="handleCheckboxChange"
            >GW</ion-checkbox>
          </div>
          <ion-button 
            class="filter-button" 
            :class="{ active: filterType === 'ALL' }"
            @click="setFilterType('ALL')"
            style="--background: Ivory; --background-activated: Ivory"
          >
            ALL
          </ion-button>
          <ion-button 
            class="filter-button" 
            :class="{ active: filterType === 'SVOM' }"
            @click="setFilterType('SVOM')"
            style="--background: Orange; --background-activated: Orange"
          >
            SVOM GRB
          </ion-button>
          <ion-button 
            class="filter-button" 
            :class="{ active: filterType === 'OTHER' }"
            @click="setFilterType('OTHER')"
            style="--background: LightGreen; --background-activated: LightGreen"
          >
            OTHER GRB
          </ion-button>
          <ion-button 
            :class="{ active: filterType === 'LIGO/Virgo' }"
            @click="setFilterType('LIGO/Virgo')"
            style="--background: Khaki; --background-activated: Khaki"
            class="filter-button"
          >
            GW
          </ion-button>
          <ion-button 
            :class="{ active: filterType === 'OTHER_TELESCOPE' }"
            @click="setFilterType('OTHER_TELESCOPE')"
            style="--background: LightSteelBlue; --background-activated: LightSteelBlue"
            class="filter-button"
          >
            Other
          </ion-button>
          <ion-button 
            expand="block" 
            fill="outline" 
            color="primary" 
            class="filter-button save-button"
            @click="saveFilterType"
          >
            Save
            <ion-icon :icon="saveOutline" slot="end"></ion-icon>
          </ion-button>
        </div>
      </ion-toolbar>
    </ion-header>
    
    <ion-content @ionScroll="handleScroll($event)" scrollEvents="true">
      <span>&nbsp;</span>Update at:{{ data }}
      <div v-if="showNoDataMessage" class="no-data-message">
        No data available
      </div>
      <div v-else v-for="item in displayedItems" :key="item.triggerId">
        <ion-card 
          class="card" 
          :style="{ backgroundColor: getCardColor(item) }"
          @click="toggleCard(item.triggerId)"
        >
          <ion-card-header>
            <ion-card-title class="space-between">
              {{ item.triggerName }}
              <span class="spacer"></span>
              {{ item.triggerTelescopeName}}
              <span 
                v-if="item.triggerTelescopeName === 'SVOM' && item.triDetectors && item.triggerTypeName?.toLowerCase() !== 'other'" 
                class="detector-box"
              >
                {{ formatDetectors(item.triDetectors) }}
              </span>
              <ion-icon 
                :icon="expandedCards[item.triggerId] ? chevronDown : chevronForward" 
                size="large"
              />
            </ion-card-title>
          </ion-card-header>
          
          <ion-card-content v-if="expandedCards[item.triggerId]">
            <div class="content">
              <ion-grid>
                <ion-row>
                  <ion-col size="5">EVENT NAME: </ion-col>
                  <ion-col size="7">{{ item.eventName }}</ion-col>
                  
                  <ion-col size="5">TIME:
                    <ion-icon 
                      style="font-size: 20px" 
                      aria-hidden="true" 
                      :icon="helpCircleOutline" 
                      @click.stop="showTooltip1 = true"
                    >
                      <ion-popover :is-open="showTooltip1" @didDismiss="showTooltip1 = false">
                        <ion-header class="bg"><span>&nbsp;&nbsp;&nbsp;</span>1</ion-header>
                        <ion-content class="ion-padding">Trigger Time(T0),in UT,is retrived from the latest alert packet.</ion-content>
                      </ion-popover>
                    </ion-icon> 
                  </ion-col>
                  <ion-col size="7">{{ item.triggerTime }}</ion-col>
                  
                  <ion-col size="5">REAL: </ion-col>
                  <ion-col size="7" :style="{ color: textColor }">{{ validate(item.validated) }} </ion-col>
                  
                  <ion-col size="5">RA:
                    <ion-icon 
                      style="font-size: 20px" 
                      aria-hidden="true" 
                      :icon="helpCircleOutline" 
                      @click.stop="showTooltip2 = true"
                    >
                      <ion-popover :is-open="showTooltip2" @didDismiss="showTooltip2 = false">
                        <ion-header class="bg"><span>&nbsp;&nbsp;&nbsp;</span>2</ion-header>
                        <ion-content class="ion-padding">Coordinates(in J2000 epoch) and Err,are retrived from the latest packet.</ion-content>
                      </ion-popover>
                    </ion-icon>
                  </ion-col>
                  <ion-col size="7">{{ item.triggerRaStr }}</ion-col>
                  
                  <ion-col size="5">DEC: </ion-col>
                  <ion-col size="7">{{ item.triggerDecStr }} </ion-col>
                  
                  <ion-col size="5">ERR: </ion-col>
                  <ion-col size="7">
                    {{ convertToDegMin(item.triggerErr) }} 
                    <select 
                      v-model="selectedUnit" 
                      @click.stop
                      @change.stop
                    >
                      <option v-for="unit in units" :key="unit.value" :value="unit.value">
                        {{ unit.value }}
                      </option>
                    </select>
                  </ion-col>
                </ion-row>
                <div class="button-container">
                  <ion-button 
                    expand="block" 
                    fill="outline" 
                    color="primary" 
                    @click.stop="goToDetail(item.triggerName)"
                    class="detail-button"
                  >
                    <ion-icon :icon="chevronForward" slot="end"></ion-icon>
                    Check
                  </ion-button>
                </div>
              </ion-grid>
            </div>
          </ion-card-content>
        </ion-card>
      </div>
      <div v-if="loadingMore" class="loading-more">
        <ion-spinner name="crescent"></ion-spinner>
        <span>Loading...</span>
      </div>
      <div v-if="allLoaded && !showNoDataMessage" class="all-loaded">
        It's the last one
      </div>
    </ion-content>
  </ion-page>
</template>

<script setup>
import { useRouter } from 'vue-router';
const router = useRouter();
import { 
  IonCard,
  IonCardContent,
  IonCardHeader,
  IonCardTitle,
  IonPage,
  IonPopover,
  IonIcon,
  IonGrid, 
  IonCol, 
  IonRow, 
  IonContent,
  IonHeader,
  IonSearchbar,
  IonToolbar,
  IonButton,
  IonCheckbox,
  IonSpinner,
} from '@ionic/vue';
import { helpCircleOutline, chevronDown, chevronForward,saveOutline } from 'ionicons/icons';
import service from '@/api/api'
import { ref, onMounted, watch, nextTick } from 'vue';
import { onIonViewDidEnter } from '@ionic/vue';
import services from '@/api/test'
const textColor = ref('red');
const showTooltip1 = ref(false);
const showTooltip2 = ref(false);
const searchQuery = ref('');
const filterType = ref('ALL');
const originalItems = ref([]);
const expandedCards = ref({});
const data = ref('');
const items = ref([]);
const showGRB = ref(false);
const showGW = ref(false);
const selectedUnit = ref('DEG');
const loadingMore = ref(false);
const allLoaded = ref(false);
const currentPage = ref(1);
const pageSize = ref(80);
const displayedItems = ref([]);
const totalItems = ref(0);
const lastResponseCount = ref(0); 
const MIN_DISPLAY_ITEMS = 8;
const showNoDataMessage = ref(false);
const savedFilterType = ref('ALL'); // 新增：保存到数据库的filterType值

const unit = [
  { value: 'DEG' },
  { value: 'MIN'},
  { value: 'SEC' },
];
const units = ref(unit);

const formatDetectors = (detectors) => {
  if (!detectors) return '';
  if (Array.isArray(detectors)) {
    return detectors.join('+');
  }
  if (typeof detectors === 'string') {
    return detectors.replace(/,/g, '+');
  }
  return '';
};

const fetchData = async (page = 1, isLoadMore = false) => {
  try {
    if (loadingMore.value) return;
    
    loadingMore.value = true;
    
    const response = await service.post('/alertApi/getTriggers', {
      start: (page - 1) * pageSize.value,
      length: pageSize.value
    });
    
    const response1 = await service.get('/alertApi/getLastTime');
    data.value = response1.data.data;
    
    const nonTestItems = response.data.data.list.filter(item => !item.isTest);
    lastResponseCount.value = response.data.data.list.length;
    
    if (isLoadMore) {
      originalItems.value = [...originalItems.value, ...nonTestItems];
      items.value = [...items.value, ...nonTestItems];
    } else {
      originalItems.value = nonTestItems;
      items.value = nonTestItems;
      totalItems.value = response.data.data.total || 0;
      currentPage.value = 1;
      allLoaded.value = false;
    }
    
    applyFilter();
    
    if (lastResponseCount.value < pageSize.value) {
      allLoaded.value = true;
    }
    
    const initialExpandedState = {};
    items.value.forEach(item => {
      initialExpandedState[item.triggerId] = expandedCards.value[item.triggerId] || false;
    });
    expandedCards.value = initialExpandedState;
    
  } catch (error) {
    console.error('Error fetching data:', error);
    if (isLoadMore) {
      currentPage.value -= 1;
    }
  } finally {
    loadingMore.value = false;
  }
}

const updateLocalSettings = (settings) => {
  showGRB.value = settings.showGRB !== undefined ? settings.showGRB : false;
  showGW.value = settings.showGW !== undefined ? settings.showGW : false;
  savedFilterType.value = settings.filterType || 'ALL';
  filterType.value = savedFilterType.value; // 初始化时使用数据库中的值
  applyFilter();
};

const saveSettingsToLocalStorage = (settings) => {
  localStorage.setItem('userSettings', JSON.stringify({
    name: settings.name || localStorage.getItem('name'),
    showGRB: settings.showGRB !== undefined ? settings.showGRB : showGRB.value,
    showGW: settings.showGW !== undefined ? settings.showGW : showGW.value,
    filterType: settings.filterType || savedFilterType.value
  }));
};

const resetToDefaultSettings = () => {
  showGRB.value = false;
  showGW.value = false;
  savedFilterType.value = 'ALL';
  filterType.value = 'ALL';
  saveSettingsToLocalStorage({
    name: localStorage.getItem('name'),
    showGRB: false,
    showGW: false,
    filterType: 'ALL'
  });
};

const handleScroll = (event) => {
  const scrollEl = event.target;
  const scrollHeight = scrollEl.scrollHeight;
  const scrollTop = scrollEl.scrollTop;
  const clientHeight = scrollEl.clientHeight;
  
  const threshold = 50;
  const isNearBottom = scrollHeight - (scrollTop + clientHeight) < threshold;
  
  if (isNearBottom && !loadingMore.value && !allLoaded.value && lastResponseCount.value >= pageSize.value && !showNoDataMessage.value) {
    loadMoreData();
  }
};

const loadMoreData = async () => {
  if (loadingMore.value || allLoaded.value || showNoDataMessage.value) return;
  
  currentPage.value += 1;
  await fetchData(currentPage.value, true);
};

const checkAutoLoadMore = async () => {
  if (showNoDataMessage.value) return;
  
  await nextTick();
  if (displayedItems.value.length < MIN_DISPLAY_ITEMS && 
      !loadingMore.value && 
      !allLoaded.value && 
      lastResponseCount.value >= pageSize.value) {
    await loadMoreData();
    if (displayedItems.value.length < MIN_DISPLAY_ITEMS && !allLoaded.value) {
      await checkAutoLoadMore();
    }
  }
};

const loadUserSettings = async () => {
  try {
    const userId = localStorage.getItem('userId');
    const phone = localStorage.getItem('phone');
    
    if (!userId) {
      const localSettings = localStorage.getItem('userSettings');
      if (localSettings) {
        updateLocalSettings(JSON.parse(localSettings));
      } else {
        resetToDefaultSettings();
      }
      return;
    }

    const config = {
      headers: {
        'X-User-Id': userId,
        'Cache-Control': 'no-cache, no-store, must-revalidate',
        'Pragma': 'no-cache',
        'Expires': '0'
      },
      timeout: 10000
    };

    const response = await services.get('/api/settings', config);
    
    if (response.data) {
      const settings = response.data;
      updateLocalSettings(settings);
      saveSettingsToLocalStorage(settings);
      
      if (phone && !settings.mobile) {
        await saveUserSettings();
      }
    } else {
      const localSettings = localStorage.getItem('userSettings');
      if (localSettings) {
        updateLocalSettings(JSON.parse(localSettings));
      } else {
        resetToDefaultSettings();
      }
    }
  } catch (error) {
    console.error('Error loading user settings:', error);
    const localSettings = localStorage.getItem('userSettings');
    if (localSettings) {
      updateLocalSettings(JSON.parse(localSettings));
    } else {
      resetToDefaultSettings();
    }
  }
};

const handleCheckboxChange = () => {
  if ((filterType.value === 'LIGO/Virgo' && !showGW.value) || 
      (showGRB.value && (filterType.value === 'LIGO/Virgo' || filterType.value === 'OTHER_TELESCOPE'))) {
    showNoDataMessage.value = true;
    displayedItems.value = [];
  } else {
    showNoDataMessage.value = false;
    applyFilter();
  }
  
  checkNetworkAndSave();
};

const setFilterType = async (type) => {
  filterType.value = type;
  
  if ((type === 'LIGO/Virgo' && !showGW.value) || 
      (showGRB.value && (type === 'LIGO/Virgo' || type === 'OTHER_TELESCOPE'))) {
    showNoDataMessage.value = true;
    displayedItems.value = [];
  } else {
    showNoDataMessage.value = false;
    applyFilter();
  }
  
  // 不再自动保存到数据库，只更新本地状态
  saveSettingsToLocalStorage({
    filterType: savedFilterType.value // 保持保存的是上一次保存的值
  });
};

// 新增：保存filterType到数据库
const saveFilterType = async () => {
  savedFilterType.value = filterType.value;
  
  saveSettingsToLocalStorage({
    filterType: savedFilterType.value
  });
  
  if (navigator.onLine) {
    try {
      const userId = localStorage.getItem('userId');
      if (!userId) return;
      
      const config = {
        headers: {
          'X-User-Id': userId,
          'Cache-Control': 'no-cache',
          'Content-Type': 'application/json'
        },
        timeout: 10000
      };
      
      await services.post('/api/settings', { 
        filterType: savedFilterType.value 
      }, config);
    } catch (error) {
      console.error('Error saving filter type:', error);
    }
  }
};

const checkNetworkAndSave = async () => {
  if (navigator.onLine) {
    await saveUserSettings();
  } else {
    const settings = {
      name: localStorage.getItem('name'),
      showGRB: showGRB.value,
      showGW: showGW.value,
      filterType: savedFilterType.value
    };
    saveSettingsToLocalStorage(settings);
    console.log('Offline mode - settings saved locally only');
  }
};

const saveUserSettings = async () => {
  try {
    const userId = localStorage.getItem('userId');
    const name = localStorage.getItem('name');
    const phone = localStorage.getItem('phone');
    
    if (!userId) return;
    
    const settings = {
      name: name,
      showGRB: showGRB.value,
      showGW: showGW.value,
      filterType: savedFilterType.value,
      mobile: phone
    };
    
    const config = {
      headers: {
        'X-User-Id': userId,
        'Cache-Control': 'no-cache',
        'Content-Type': 'application/json'
      },
      timeout: 10000
    };
    
    await services.post('/api/settings', settings, config);
  } catch (error) {
    console.error('Error saving user settings:', error);
  }
};

watch(() => localStorage.getItem('userId'), (newUserId) => {
  if (newUserId) {
    loadUserSettings();
  }
});

onMounted(() => {
  loadUserSettings().then(() => {
    fetchData();
  });
  
  setInterval(() => {
    doRefresh();
  }, 120000);
});

const toggleCard = (triggerId) => {
  expandedCards.value = {
    ...expandedCards.value,
    [triggerId]: !expandedCards.value[triggerId]
  };
};

const goToDetail = (triggerName) => {
  router.push({
    name: 'eventdetails',
    params: { triggerName }, 
  });
};

const getCardColor = (item) => {
  if (item.triggerTypeName?.toLowerCase() === 'other') {
    return 'LightSteelBlue';
  }
  switch (item.triggerTelescopeName) {
    case 'SVOM':
      return 'Orange';
    case 'LIGO/Virgo':
      return 'Khaki';
    default:
      return 'LightGreen';
  }
};

async function doRefresh() {
  await fetchData(1);
}

const applyFilter = async () => {
  if (showNoDataMessage.value) return;
  
  const query = searchQuery.value.toLowerCase();
  
  let filteredItems = originalItems.value.filter(item => !item.isTest);
  
  if (!showGW.value) {
    filteredItems = filteredItems.filter(item => item.triggerTelescopeName !== 'LIGO/Virgo');
  }
  
  if (!showGRB.value) {
    filteredItems = filteredItems.filter(item => {
      if (item.triggerTelescopeName === 'SVOM') {
        if (item.triDetectors) {
          const detectors = Array.isArray(item.triDetectors) 
            ? item.triDetectors 
            : typeof item.triDetectors === 'string' 
              ? item.triDetectors.split(',') 
              : [];
          return !detectors.includes('GRM');
        }
      }
      return true;
    });
  } else {
    filteredItems = filteredItems.filter(item => {
      if (item.triggerTelescopeName === 'SVOM') {
        return item.triggerTypeName?.toLowerCase() !== 'other';
      }
      return true;
    });
  }
  
  if (filterType.value !== 'ALL') {
    filteredItems = filteredItems.filter(item => {
      if (filterType.value === 'SVOM') {
        return item.triggerTelescopeName === 'SVOM' && item.triggerTypeName?.toLowerCase() !== 'other';
      }
      if (filterType.value === 'LIGO/Virgo') return item.triggerTelescopeName === 'LIGO/Virgo';
      if (filterType.value === 'OTHER') return !['SVOM', 'LIGO/Virgo'].includes(item.triggerTelescopeName);
      if (filterType.value === 'OTHER_TELESCOPE') return item.triggerTypeName?.toLowerCase() === 'other';
      return true;
    });
  }
  
  if (query) {
    filteredItems = filteredItems.filter(item =>
      item.triggerName.toLowerCase().includes(query) ||
      item.triggerTelescopeName.toLowerCase().includes(query)
    );
  }
  
  items.value = filteredItems;
  displayedItems.value = filteredItems;
  
  const newExpandedCards = {};
  filteredItems.forEach(item => {
    newExpandedCards[item.triggerId] = expandedCards.value[item.triggerId] || false;
  });
  expandedCards.value = newExpandedCards;
  
  await checkAutoLoadMore();
};

const handleInput = (event) => {
  searchQuery.value = event.target.value.toLowerCase();
  applyFilter();
};

onIonViewDidEnter(() => {
  applyFilter();
});

const validate = (validated) => {
  if(validated!==null){
    if(validated===true){
      return 'Y';
    }else{
      return 'N';
    }
  }else{
    return '';
  }  
}

const convertToDegMin = (triggerErr) => {
  const minute = triggerErr * 1;
  const minutes = triggerErr * 60;
  const minutes1 = triggerErr * 3600;
  if(triggerErr!==null){
    switch (selectedUnit.value) {
      case 'DEG':
        return ` ${minute.toFixed(4)}`;
      case 'MIN':
        return ` ${minutes.toFixed(4)}`;
      default:
        return ` ${minutes1.toFixed(4)}`;
    }
  }
};

window.doRefresh = doRefresh;
</script>

<style scoped>
.eye {
  background-color: NavajoWhite;
}

ion-col {
  text-align: start;
}

.content {
  background-color: white;
}

.card {
  font-family: 'Arial', sans-serif;
  margin-bottom: 8px;
  cursor: pointer;
}

.space-between {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 1.7em;
} 

.spacer {
  width: 50%; 
}

.bg {
  background-color: gold;
}

ion-popover::part(backdrop) {
  background: transparent !important;
}

.button-container {
  display: flex;
  justify-content: flex-end;
  margin-top: 10px;
}

.detail-button {
  --padding-top: 8px;
  --padding-bottom: 8px;
  --padding-start: 16px;
  --padding-end: 16px;
  font-size: 12px;
  font-weight: bold;
  width: auto;
  min-width: 80px;
  --background: white;
  --background-activated: #f0f0f0;
  --color: black;
  --color-activated: black;
  --border-color: var(--ion-color-primary);
  --border-radius: 6px;
  --box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  height: auto;
  line-height: 1.2;
  transition: all 0.2s ease;
  --border-width: 2px;
}

.detail-button:hover {
  transform: translateY(-1px);
  --box-shadow: 0 3px 6px rgba(0,0,0,0.15);
  --background: #f8f8f8;
}

.filter-buttons {
  display: flex;
  justify-content: space-between;
  padding: 2px;
  align-items: center;
}

.checkbox-container {
  display: flex;
  flex-direction: column;
  margin-right: 4px;
  height: 100%;
  justify-content: space-between;
  gap: 6px;
  min-width: 60px;
}

.small-checkbox {
  --size: 14px;
  font-size: 10px;
  margin: 0;
  padding: 0;
  height: 14px;
  line-height: 1;
  --border-radius: 2px;
  --border-width: 1px;
  --border-color: #666;
  --border-color-checked: #666;
  --background-checked: #666;
  --checkmark-color: white;
  --checkmark-width: 2px;
  margin-right: 4px;
  display: flex;
  align-items: center;
}

.small-checkbox::part(label) {
  margin-left: 4px;
  flex: 1;
  text-align: right;
  white-space: nowrap;
}

.gw-checkbox::part(label) {
  padding-right: 27px;
}

.filter-button {
  flex: 1;
  min-width: calc(14% - 2px);
  margin: 0 1px;
  font-weight: bold;
  font-size: 8.5px;
  --border-radius: 4px;
  --color: black;
  --color-activated: black;
  --background: var(--ion-color-light);
  --background-activated: var(--ion-color-light);
  height: 32px;
  min-height: 32px;
  white-space: nowrap;
  line-height: 1.1;
  padding: 0 2px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.filter-button.active {
  --background-activated: var(--background);
  font-weight: bolder;
}

.save-button {
  min-width: calc(14% - 2px);
  --background: LightPink;
  --background-activated: LightPink;
}

.custom-segment {
  padding: 2px;
}

.custom-segment ion-segment-button {
  --indicator-color: transparent;
  --color: black;
  --color-checked: black;
  border-radius: 4px;
  margin: 0 1px;
  font-weight: bold;
  min-height: 28px;
  height: auto;
  min-width: calc(20% - 2px);
  flex: 1;
}

.segment-label {
  white-space: normal;
  line-height: 1.1;
  padding: 1px 0;
  font-size: 10px;
}

ion-segment-button::part(indicator) {
  height: 100%;
}

.loading-more, .all-loaded, .no-data-message {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 10px;
  color: #666;
}

.loading-more ion-spinner {
  margin-right: 8px;
}

.detector-box {
  background-color: white;
  border-radius: 4px;
  padding: 2px 6px;
  margin-left: 8px;
  font-size: 0.8em;
  font-weight: bold;
  border: 1px solid rgba(0, 0, 0, 0.1);
}
</style>